<?php
class lanzou{
    private $UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54';
    private $UserAgentIOS = 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89 MicroMessenger/7.0.17(0x1700112a) NetType/WIFI Language/zh_CN';
    private $base_domain = 'https://xiaoggvip.lanzouc.com';
    private $lz_cookie ="ylogin=792805; phpdisk_info=V2RSaVU1ADQENgNmCFsGaAdeUWJaaaaaaaacwVzQGMgUOATBePVtkUmYEZ108XDNXbbbbbUmdVZAA7BDMDMggwBj0HZFFnXDZTMANjVzFVYVFjVmIHPFcyBjMFMAFYXjVbNFIyBDVdNlw9V2QEYwIxV2RXaw%3D%3D;";
    public function getUrl($url,$pwd=''){
        $return =array('status'=>0,'info'=>'');
        if(empty($url)){$return['info']= '请输入URL';return $return;}
        $softInfo = $this->str_exists($url,'http')?$this->curlget($url):'';
        if(empty($softInfo)){
            $url = $this->format_url($url);
            $softInfo = $this->curlget($url);
            if($this->str_exists($str,'404 Not Found')){
                $return['info']= '请稍后重试';return $return;
            }
        }
        if(empty($softInfo)){$return['info']= '链接无法访问'.$url;return $return;}
        if ($this->str_exists($softInfo, "文件取消分享了")) {$return['info']= '文件取消分享了';return $return;}
        if ($this->str_exists($softInfo, "手机Safari可在线安装")) {
          	if($this->str_exists($softInfo, "n_file_infos")){
              	$ipaInfo = $this->curlget($url,'','GET' ,array(),$this->UserAgentIOS);
            	preg_match('~href="(.*?)" target="_blank" class="appa"~', $ipaInfo, $ipaDownUrl);
            }else{
            	preg_match('~com/(\w+)~', $url, $lanzouId);
                if (!isset($lanzouId[1])) {$return['info']= '解析失败，获取不到文件ID';return $return;}
                $lanzouId = $lanzouId[1];
                $ipaInfo = $this->curlget($this->base_domain."/tp/" . $lanzouId,'','GET' ,array(), $this->UserAgentIOS);
                preg_match('~href="(.*?)" id="plist"~', $ipaInfo, $ipaDownUrl);
            }
            $ipaDownUrl = isset($ipaDownUrl[1]) ? $ipaDownUrl[1] : "";
            if($ipaDownUrl){
                $return['status']=1;
                $return['info']=$ipaDownUrl;
                return $return;
            }
        }
        if($this->str_exists($softInfo, "filemoreajax")){$return['info']= '暂不支持文件夹获取';return $return;}
        if (preg_match('/<iframe\s+class="(ifr2|n_downlink)".*?src="(\/fn\?\w{3,}?)".*?><\/iframe>/i', $softInfo, $m)) {
			// 不需要访问密码
			$html = $this->curlget(self::url_fix($this->base_domain, $m[2]));
			if (false !== $ajax = self::html_ajax($html)) {
				$ret = $this->curlget(self::url_fix($this->base_domain, $ajax['url']), $ajax['data'],'POST');
			}
		} else if (false !== $ajax = self::html_ajax($softInfo)) {
			// 需要访问密码
			if ($pwd === ''){$return['info']= '需要访问密码';return $return;}
			$ajax['data']['p'] = $pwd;
			$ret  = $this->curlget(self::url_fix($this->base_domain, $ajax['url']), $ajax['data'],'POST');
		}
        $softInfo = json_decode($ret, true);
        if ($softInfo['zt'] != 1) {if(empty($softInfo['inf']))$softInfo['inf']='获取失败';$return['info']= $softInfo['inf'];return $return;}
        $downUrl1 = $softInfo['dom'] . '/file/' . $softInfo['url'];$downUrl2='';
        //解析最终直链地址
        $downUrlres = $this->get_head($downUrl1,$this->base_domain,"down_ip=1; expires=Sat, 16-Nov-2019 11:42:54 GMT; path=/; domain=.baidupan.com");
        if(!empty($downUrlres['redirect_url'])){
            $downUrl2=$downUrlres['redirect_url'];
        }else{
            $ajax               = self::html_ajax($downUrlres['data']);
			$ajax['data']['el'] = 2;sleep(2);// 这里必须加上延迟2秒
            $ret = $this->curlget(self::url_fix($this->base_domain, $ajax['url']), $ajax['data'],'POST');
            $ret = json_decode($ret, true);
            if(!empty($ret['url'])){$downUrl2 = $ret['url'];}
        }
        $downUrl = $downUrl2?$downUrl2:$downUrl1;
        if(empty($downUrl)){$return['info']= '获取下载地址失败';return $return;}
        $return['status']=1;
        $return['info']=$downUrl;
        return $return;
    }    
	/**
	 * 提取html源码中的script代码并过滤掉干扰函数
	 *
	 * @param  string  $html  html源码
	 * @param  string  $fun   干扰函数名正则
	 *
	 * @return string
	 */
	private static function html_script ($html, $fun = 'woio\d*') {
		$script = '';
		if (preg_match_all('#<script.*?>([\s\S]*?)</script>#i', $html, $m) > 0) {
			$script = implode("\n", $m[1]);
			$script = preg_replace("#(^|\n)\s*function\s*{$fun}\s*(.*?)\s*\{[\s\S]*?\}\s*(\n|$)#i", '', $script);
		}
		return $script;
	}
    /**
	 * 提取html源码中的ajax并解析data中的变量
	 *
	 * @param  string  $html  html源码
	 *
	 * @return array|false
	 */
	private static function html_ajax ($html) {
		$script = self::html_script($html);
		if (preg_match('/[,{\n]\s*url\s*:\s*[\'"](.+?)[\'"]\s*,(?:[\s\S]*?\n+)?\s*data\s*:\s*{([\s\S]*?)}\s*,/i', $script, $m)) {
			return ['url' => $m[1], 'data' => self::ajax_data($m[2], $script)];
		}
		return false;
	}
	private static function url_fix ($host, $url) {
		return preg_match('#^(https?:)?//#i', $url) ? $url
			: rtrim($host, '/') . '/' . ltrim($url, '/');
	}
	/**
	 * 提取ajax中的data并解析其中的变量
	 *
	 * @param  string  $data    data字符串
	 * @param  string  $script  script代码，用于提取解析data中的变量
	 *
	 * @return array|string[]
	 */
	private static function ajax_data ($data, $script) {
		if (!preg_match_all('/[\'"](\w+)[\'"]\s*:\s*([\w\'"]+)/', $data, $m))
			return [];
		$data = array_combine($m[1], $m[2]);
		if (preg_match_all('/\n\s*(var\s*)?([a-zA-Z_]\w*)\s*=\s*([\'"](.*)[\'"]|\d+)\s*;/', $script, $m) > 0) {
			$vars = array_combine($m[2], $m[3]);
			$data = array_map(function ($v) use ($vars) {
				return trim(preg_match('/^([a-zA-Z_]\w*)$/', $v) ? isset($vars[$v]) ? $vars[$v] : '' : $v, '"\'');
			}, $data);
		}
		return $data;
	}
    //直链解析函数
    private function get_head($url,$guise,$cookie){
        $headers = array(
        	'Accept:text/html,application/xhtml+xml,application/xml',
        	'Accept-Encoding: gzip, deflate','Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
			'X-Forwarded-For: '. $_SERVER['REMOTE_ADDR']
        );
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER,$headers);
        curl_setopt($curl, CURLOPT_REFERER, $guise);
        curl_setopt($curl, CURLOPT_COOKIE , $cookie.'; '.$this->lz_cookie);
        curl_setopt($curl, CURLOPT_USERAGENT,$this->UserAgent);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        $data = curl_exec($curl);
        $url=curl_getinfo($curl);
        curl_close($curl);
        
        return array('redirect_url'=>$url["redirect_url"],'data'=>$data);
    }
    /**
     * CURL发送HTTP请求
     * @param  string $url    请求URL
     * @param  array  $params 请求参数
     * @param  string $method 请求方法GET/POST
     * @param  $header 头信息
     * @param  $multi  是否支付附件
     * @param  $debug  是否输出错误
     * @param  $optsother 附件项
     * @return array  $data   响应数据
     */
    private function curlget($url, $params='', $method = 'GET', $header = array(), $UserAgent = false,$debug=false,$optsother='') {
        if(empty($UserAgent))$UserAgent=$this->UserAgent;
        $header[]='accept: text/html,application/xhtml+xml,application/xml';
        $header[]='accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6';
        $header[]='X-Forwarded-For: '.$_SERVER['REMOTE_ADDR'];
        if(empty($optsother[CURLOPT_REFERER]))$optsother[CURLOPT_REFERER]='https://pan.lanzou.com/';
        if(empty($optsother[CURLOPT_COOKIE])){
            $optsother[CURLOPT_COOKIE]=$this->lz_cookie;
        }
    	$opts = array(CURLOPT_TIMEOUT => 10,CURLOPT_RETURNTRANSFER=> 1,CURLOPT_SSL_VERIFYPEER=> false,CURLOPT_SSL_VERIFYHOST=> false,CURLOPT_HTTPHEADER => $header,CURLOPT_USERAGENT=>$UserAgent);		
    	switch (strtoupper($method)) {/* 根据请求类型设置特定参数 */
    		case 'GET':$opts[CURLOPT_URL] = $params?$url.'?'.http_build_query($params):$url;break;
    		case 'POST':$params = http_build_query($params);//判断是否传输文件
        	$opts[CURLOPT_URL] = $url;$opts[CURLOPT_POST] = 1;$opts[CURLOPT_POSTFIELDS] = $params;break;			
    		default:if($debug)echo ('不支持的请求方式！');break;
    	}$ch = curl_init();if($optsother && is_array($optsother))$opts=$opts+$optsother;curl_setopt_array($ch, $opts);$data = curl_exec($ch);$error = curl_error($ch);curl_close($ch);/* 初始化并执行curl请求 */
    	if($error && $debug){echo ('请求发生错误:'.$error);}
    	return $data;
    }//检测字符串中是否存在
    private function str_exists($haystack, $needle){
    	return !(strpos(''.$haystack, ''.$needle) === FALSE);
    }//重购url
    private function format_url($url){       
        if($this->str_exists($url,'.com')){
            $arr = explode('.com',$url);
            $urlbase = $arr[1];
        }else{
            $urlbase='/'.$url;  
        }
        return $this->base_domain.$urlbase;
    }
}
?>